/*
 * 之前我们已经看到了如何描述索引。我们还必须声明如何存储它。这就是我们需要迁移的地方。
 * 迁移由框架自动运行（在您在服务提供程序中注册它之后）。您可以使用它们来描述数据库架构更改。
 * 这里是关于迁移的文档页面：
 * https://docs.orchardcore.net/en/latest/docs/reference/modules/Migrations/.
 */

using Ruitu.Edu.TrainingDemo.Indexes;
using OrchardCore.Data.Migration;
using System.Threading.Tasks;
using YesSql.Sql;

namespace Ruitu.Edu.TrainingDemo.Migrations;

// 不要忘记在服务提供程序中注册此类（参见：Startup.cs）。
public sealed class BookMigrations : DataMigration
{
    // 迁移有 Create() 和 UpdateFromX 方法。当模块首次启用时，会调用 Create() 以便它可以设置数据库表。
    public async Task<int> CreateAsync()
    {
        await SchemaBuilder.CreateMapIndexTableAsync<BookIndex>(table => table
            .Column<string>(nameof(BookIndex.Author))
            // 书籍标题有时可能真的很长（甚至长达26000个字符：
            // https://www.guinnessworldrecords.com/world-records/358711-longest-title-of-a-book) 所以我们必须确保
            // 它能适合列。默认情况下，文本列的限制为255个字符，所以我们必须强制执行这个限制，
            // 并在确实需要空间的情况下使其无限制。
            .Column<string>(nameof(BookIndex.Title), column => column.Unlimited())
        );

        // 假设我们将在数据库中存储许多书籍，数万本。在这种情况下，还建议为经常查询的列添加SQL索引。
        // 在我们的例子中，Author就是这样的，所以我们在下面添加了一个索引。注意，您只能在 AlterTable() 中添加索引。
        await SchemaBuilder.AlterTableAsync(nameof(BookIndex), table => table
            .CreateIndex($"IDX_{nameof(BookIndex)}_{nameof(BookIndex.Author)}", nameof(BookIndex.Author))
        );

        // 这里我们返回迁移的版本号。如果没有更新方法，我们会返回1。但我们有一个，请查看它以了解更多详细信息。
        return 2;
    }

    // 这是一个更新方法。它用于修改现有架构。当模块之前已经启用并且创建方法已经运行
    // （比如当您更新已经在Orchard站点上运行的模块时）时，将运行更新方法。UpdateFromX中的X是更新的版本号
    // （方法名称是约定俗成的）。这意味着："如果模块的当前迁移版本是X，则运行此更新"。如果版本是1，此方法将运行。
    public async Task<int> UpdateFrom1Async()
    {
        // 我们模块的初始版本没有存储书籍标题。我们通过推送一个修改架构以添加Name的更新来快速修复问题。
        // 记住，我们在Create方法中返回了2，所以这个更新方法在全新设置中不会被执行。这就是为什么您还需要
        // 在Create方法中包含所有这些更改。
        await SchemaBuilder.AlterTableAsync(nameof(BookIndex), table => table
            .AddColumn<string>(nameof(BookIndex.Title))
        );

        return 2;
    }
}

// 下一站：Controllers/DatabaseStorageController 并转到我们之前离开的 CreateBooksPost 操作。
